﻿//------------------------------------------------------------------------------------------
// File: <ParameterForm.cs>
// Purpose: implement <Data entries UI for the reactor unit.>
//
// @author <Yun Hua>
// @version 1.0 2010/04/27
// 
// @Updates <2010-5-13, Yun Hua, Add routine to establish Xco with the catalyst activity, residence time.>
// Copyright (C) 2010, YUN HUA.
//-----------------------------------------------------------------------------------------//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Office.Interop.Excel;
using System.Threading;

namespace Yashen.SimLab
{
    internal partial class ParameterForm : Form
    {
        #region Private Static Members

        private static ParameterForm sDefaultForm;
        private static System.Threading.Thread sThread;
        private static FTReactorUnit mUnit;

        #endregion

        #region Private Members

        private double[] coeffs;
        private double pDrop;               // bar
        private double fixedTemperature;    // in degree C
        private double[] fracMap;
        private double[] inactiveCompsMap;
        private CalcMode mode;
        private List<IntermCalcData> calcSequence;

        #endregion

        #region Private Members For Calcualtion Mode I

        private double reactorVol;      // L
        private double kCoeff;
        private List<KeyValuePair<double/*temperature in C*/, double/*STY*/>> spaceTimeYields;
        private double selAlpha;
        private double inputTotalFlow;  // mol/s
        private double inputPressure;   // bar
        private double[] selsC1toCnAdjusted; // Adjusted C1 to Cn selectivities

        #endregion

        #region Private Members For Calcualtion Mode II

        private double k1Coeff; // k1 coupling with H2/CO ratio
        private double k2Coeff; // k2 coupling with H2/CO ratio
        private double ratioH2CO; // The mole ratio of H2 to CO

        #endregion

        #region Constructors

        public ParameterForm()
        {
            InitializeComponent();
            comboBoxCalcMode.Items.Add(CalcMode.Simple.ToString());
            comboBoxCalcMode.Items.Add(CalcMode.ModeI.ToString());
            comboBoxCalcMode.Items.Add(CalcMode.ModeII.ToString());
        }

        #endregion

        #region Properties

        /// <summary>
        /// Get and set the user supplied conversion coefficients.
        /// </summary>
        public double[] ConvCoeffIn
        {
            get { return coeffs; }
            set 
            {
                if (value == null || value.Length == 0)
                {
                    throw new ArgumentException("Input is null or empty", "ConvCoeffIn");
                }
                coeffs = value;
                FillCoeff(coeffs);
            }
        }

        /// <summary>
        /// Set the component IDs.
        /// </summary>
        public string[] RxnID
        {
            set 
            {
                if (value == null || value.Length == 0)
                {
                    throw new ArgumentException("Input is null or empty", "RxnID");
                }
                FillRxnID(value);
            }
        }

        /// <summary>
        /// Get and set the pressure drop value.
        /// </summary>
        public double PressureDrop
        {
            get { return pDrop; }
            set 
            {
                pDrop = value;
                textBoxPDrop.Text = pDrop.ToString();
            }
        }

        /// <summary>
        /// Get the component fraction map.
        /// </summary>
        public double[] FracMap
        {
            get { return fracMap; }
            set { fracMap = value; }
        }

        /// <summary>
        /// Get and set the inactive components map.
        /// </summary>
        public double[] InactiveCompsMap
        {
            get { return inactiveCompsMap; }
            set { inactiveCompsMap = value; }
        }

        /// <summary>
        /// Get and set the fixed temperature for the isothermal reaction.
        /// </summary>
        public double FixedTemperature
        {
            get { return fixedTemperature; }
            set 
            { 
                fixedTemperature = value;
                textBoxFixTemperature.Text = fixedTemperature.ToString();
            }
        }

        /// <summary>
        /// Get and set the calulation mode.
        /// </summary>
        public CalcMode Mode
        {
            get { return mode; }
            set 
            { 
                mode = value;
                comboBoxCalcMode.SelectedIndex = comboBoxCalcMode.FindString(mode.ToString());
            }
        }

        /// <summary>
        /// Get and set the reactor volume.
        /// </summary>
        public double ReactorVol
        {
            get { return reactorVol; }
            set 
            { 
                reactorVol = value;
                textBoxReactorVol.Text = reactorVol.ToString();
                textBoxReactorVol_II.Text = reactorVol.ToString();
            }
        }

        /// <summary>
        /// Get and set the k coefficient.
        /// </summary>
        public double KCoeff
        {
            get { return kCoeff; }
            set 
            {
                kCoeff = value;
                textBoxKCoeff.Text = kCoeff.ToString();
            }
        }

        /// <summary>
        /// Get or set the k1 coefficient for calculating CH4 yield
        /// </summary>
        public double K1Coeff
        {
            get { return k1Coeff; }
            set 
            {
                k1Coeff = value;
                textBoxK1.Text = k1Coeff.ToString();
            }
        }

        /// <summary>
        /// Get or set the k2 coefficient for calculating C2+ yield
        /// </summary>
        public double K2Coeff
        {
            get { return k2Coeff; }
            set 
            { 
                k2Coeff = value;
                textBoxK2.Text = k2Coeff.ToString();
            }
        }

        /// <summary>
        /// Get and set the STYs (coupling with the temperature)
        /// </summary>
        public List<KeyValuePair<double, double>> SpaceTimeYields
        {
            get { return spaceTimeYields; }
            set 
            {
                if (value == null || value.Count == 0)
                {
                    throw new ArgumentException("Input is null or empty", "STY");
                }
                spaceTimeYields = value;
                FillSTYTable(spaceTimeYields);
            }
        }

        /// <summary>
        /// Get and set the alpha value for the selectivity calulation.
        /// </summary>
        public double SelAlpha
        {
            get { return selAlpha; }
            set 
            { 
                selAlpha = value;
                textBoxSelAlpha.Text = selAlpha.ToString();
                textBoxSelAlpha_II.Text = selAlpha.ToString();
            }
        }

        /// <summary>
        /// Set the input port's total flow.
        /// Only use for the Xco-STY calculation.
        /// </summary>
        public double InputTotalFlow
        {
            set 
            { 
                inputTotalFlow = value;
                textBoxInPortFlowRate.Text = inputTotalFlow.ToString();
                textBoxInPortFlowRate_II.Text = inputTotalFlow.ToString();
            }
        }

        /// <summary>
        /// Set the input port's pressure.
        /// Only use for the Xco-STY calculation.
        /// </summary>
        public double InputPressure
        {
            set 
            { 
                inputPressure = value;
                textBoxInPortPressure.Text = inputPressure.ToString();
                textBoxInPortPressure_II.Text = inputPressure.ToString();
            }
        }

        /// <summary>
        /// Set the mole ratio of H2 to CO.
        /// Only use for the Yield CH4, Cn+ calculation in the mode I.
        /// </summary>
        public double RatioH2CO
        {
            set 
            { 
                ratioH2CO = value;
                textBoxRatioH2CO.Text = ratioH2CO.ToString();
            }
        }

        /// <summary>
        /// Get or set the adjusted C1-Cn selectivties.
        /// </summary>
        public double[] SelsC1toCnAdjusted
        {
            set { selsC1toCnAdjusted = value;}
            get { return selsC1toCnAdjusted; }
        }

        /// <summary>
        /// Get or set the calculation sequence.
        /// </summary>
        public List<IntermCalcData> CalcSequence
        {
            get { return calcSequence; }
            set { calcSequence = value; }
        }

        #endregion

        #region Public Static Methods

        public static void Edit(FTReactorUnit unit)
        {
            mUnit = unit;

            if (sThread == null || sDefaultForm == null)
            {
                sThread = new Thread(new ParameterizedThreadStart(ParameterForm.ShowInThread));
                sThread.SetApartmentState(ApartmentState.STA);  // Otherwise, FileOpenDialog.ShowDialog() will throw exception with the debugger attached.
                sThread.Start(unit);
            }
            else
            {
                sDefaultForm.Show();
            }
        }

        #endregion

        #region Private Static Methods

        private static void ShowInThread(object unit)
        {
            ShowInThread((FTReactorUnit)unit);
        }

        private static void ShowInThread(FTReactorUnit unit)
        {
            if (sDefaultForm == null) //Dovrebbe essere sempre null
            {
                sDefaultForm = new ParameterForm();
                LoadParameterValue(unit);
            }
            sDefaultForm.Show();
            System.Windows.Forms.Application.Run(sDefaultForm);
        }

        private static void LoadParameterValue(FTReactorUnit unit)
        {
            sDefaultForm.RxnID = FTPropPackage.ConvertedIDs;
            sDefaultForm.PressureDrop = unit.PressureDrop / 100000;   // par -> bar
            sDefaultForm.FixedTemperature = unit.FixedTemperature - 273.15;  // K -> C;
            sDefaultForm.InputTotalFlow = unit.InPort.TotalFlow;
            unit.InPort.CalculateProperty(Mose.CapeOpenToolkit.UnitProxy.CapeOpenThermoMaterialPropertyType.Pressure, 
                Mose.CapeOpenToolkit.UnitProxy.CapeOpenPhaseType.Overall, 
                Mose.CapeOpenToolkit.UnitProxy.CapeOpenCalculationType.Mixture);
            sDefaultForm.InputPressure = unit.InPort.Pressure / 100000;
            if (unit.Coeffs != null)
            {
                sDefaultForm.ConvCoeffIn = unit.Coeffs;
            }
            if (unit.FracMap != null)
            {
                sDefaultForm.FracMap = unit.FracMap;
                sDefaultForm.RatioH2CO = unit.InPort.Fraction[Convert.ToInt32(unit.FracMap[FTPropPackage.INDEX_H2])] /
                    unit.InPort.Fraction[Convert.ToInt32(unit.FracMap[FTPropPackage.INDEX_CO])];
            }
            if (unit.InactiveCompsMap != null)
            {
                sDefaultForm.InactiveCompsMap = unit.InactiveCompsMap;
            }
            sDefaultForm.Mode = unit.CalcMode;

            // For calulation mode I
            if (FTPropPackage.SpaceTimeYields != null)
            {
                sDefaultForm.SpaceTimeYields = FTPropPackage.SpaceTimeYields;
            }
            if (unit.SelsC1toCnAdjusted != null)
            {
                sDefaultForm.SelsC1toCnAdjusted = unit.SelsC1toCnAdjusted;

            }
            sDefaultForm.KCoeff = unit.KCoeff;
            sDefaultForm.K1Coeff = unit.K1Coeff;
            sDefaultForm.K2Coeff = unit.K2Coeff;
            sDefaultForm.ReactorVol = unit.ReactorVol;
            sDefaultForm.SelAlpha = unit.SelAlpha;
            sDefaultForm.calcSequence = unit.CalcSequence;
        }

        #endregion

        #region UI Control Event Handlers

        /// <summary>
        /// Button OK to close the form.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event argument.</param>
        private void buttonOK_Click(object sender, EventArgs e)
        {
            mUnit.Coeffs = ConvCoeffIn;
            mUnit.PressureDrop = PressureDrop * 100000;   // bar -> par
            mUnit.FracMap = FracMap;
            mUnit.InactiveCompsMap = InactiveCompsMap;
            mUnit.FixedTemperature = FixedTemperature + 273.15;   // C -> K 
            mUnit.CalcMode = Mode;

            FTPropPackage.SpaceTimeYields = SpaceTimeYields;
            mUnit.KCoeff = KCoeff;
            mUnit.K1Coeff = k1Coeff;
            mUnit.K2Coeff = k2Coeff;
            mUnit.ReactorVol = ReactorVol;
            mUnit.SelAlpha = SelAlpha;
            mUnit.SelsC1toCnAdjusted = SelsC1toCnAdjusted;
            this.Close();
        }

        /// <summary>
        /// Button Cancel to close the form.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event argument.</param>
        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Button clicked, importing the conversion coefficients from the outside source.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event argument.</param>
        private void buttonImportConvCoeff_Click(object sender, EventArgs e)
        {
            DialogResult result = openCoeffDialog.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                List<string> cells = new List<string>();

                // Fixed conversion coefficients
                cells.Add("B2");
                cells.Add("B46");

                // Mole fractions mapping
                cells.Add("E2");
                cells.Add("E49");
                
                // K
                cells.Add("G2");
                cells.Add("G2");

                // Alpha
                cells.Add("H2");
                cells.Add("H2");

                // Fixed temperature
                cells.Add("I2");
                cells.Add("I2");

                // Pressure drop
                cells.Add("J2");
                cells.Add("J2");

                // Reactor volume
                cells.Add("K2");
                cells.Add("K2");

                // STY table
                cells.Add("M2");
                cells.Add("M24");
                cells.Add("N2");
                cells.Add("N24");

                // Adjusted C1-Cn selectivity
                cells.Add("H6");
                cells.Add("H15");

                // Inactive components mapping
                cells.Add("Q2");
                cells.Add("Q10");

                // k1,k2 coefficients considering the H2/CO ratio
                cells.Add("G28");
                cells.Add("G28");
                cells.Add("H28");
                cells.Add("H28");

                List<double[]> dataList = ImportDoubleArrayListFromExcel(openCoeffDialog.FileName, cells);
                if (dataList.Count != cells.Count / 2)
                {
                    return;
                }

                if (dataList[0].Length != listViewConvCoeffIn.Items.Count)
                {
                    return;
                }
                coeffs = dataList[0];
                FillCoeff(dataList[0]);

                if (dataList[1].Length != FTPropPackage.FT_COMPONENT_COUNT)
                {
                    return;
                }
                fracMap = dataList[1];

                kCoeff = dataList[2][0];
                selAlpha = dataList[3][0];
                fixedTemperature = dataList[4][0];
                pDrop = dataList[5][0];
                reactorVol = dataList[6][0];

                // Update UI
                textBoxKCoeff.Text = kCoeff.ToString();
                textBoxSelAlpha.Text = selAlpha.ToString();
                textBoxSelAlpha_II.Text = selAlpha.ToString();
                textBoxFixTemperature.Text = fixedTemperature.ToString();
                textBoxPDrop.Text = pDrop.ToString();
                textBoxReactorVol.Text = reactorVol.ToString();
                textBoxReactorVol_II.Text = reactorVol.ToString();
                if (spaceTimeYields == null)
                {
                    spaceTimeYields = new List<KeyValuePair<double, double>>();
                }
                spaceTimeYields.Clear();
                for (int i = 0; i < dataList[7].Length; ++i)
                {
                    if (dataList[7][i] != 0)
                    {
                        spaceTimeYields.Add(new KeyValuePair<double, double>(dataList[7][i], dataList[8][i]));
                    }
                }
                FillSTYTable(spaceTimeYields);

                List<double> tempList = new List<double>();
                for (int i = 0; i < dataList[9].Length; ++i)
                {
                    if (dataList[9][i] != 0)
                    {
                        tempList.Add(dataList[9][i]);
                    }
                }
                selsC1toCnAdjusted = tempList.ToArray();

                tempList.Clear();
                for (int i = 0; i < dataList[10].Length; ++i)
                {
                    if (dataList[10][i] != 0)
                    {
                        tempList.Add(dataList[10][i]);
                    }
                }
                inactiveCompsMap = tempList.ToArray();

                // Update the k1, k2 coefficient
                k1Coeff = dataList[11][0];
                k2Coeff = dataList[12][0];
                textBoxK1.Text = k1Coeff.ToString();
                textBoxK2.Text = k2Coeff.ToString();
            }
        }

        /// <summary>
        /// Button clicked, export ConvCoeffIn to the outside source.
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event argument</param>
        private void buttonExportConvCoeff_Click(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// Validate the pressure drop and exchange the value.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void textBoxPDrop_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxPDrop, ref pDrop);
        }

        /// <summary>
        /// Validate the fixed temperature and exchange the value.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void textBoxFixTemperature_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxFixTemperature, ref fixedTemperature);
        }

        /// <summary>
        /// User selects the calulation mode.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void comboBoxCalcMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxCalcMode.SelectedItem == null)
            {
                return;
            }

            mode = (CalcMode)Enum.Parse(typeof(CalcMode), comboBoxCalcMode.SelectedItem.ToString());
        }

        /// <summary>
        /// Handle the form closed event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void ParameterForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Windows.Forms.Application.Exit();
            sDefaultForm = null;
        }

        /// <summary>
        /// Export the calculation sequence data into the file.
        /// </summary>
        /// <param name="sender">The evnet sender.</param>
        /// <param name="e">The event arguments.</param>
        private void buttonExportCalcSeq_Click(object sender, EventArgs e)
        {
            ExportCalcSequence();
        }

        /// <summary>
        /// Clear all calculation interim data.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void buttonClearCalcSeq_Click(object sender, EventArgs e)
        {
            if (calcSequence.Count == 0)
            {
                return;
            }

            string info = calcSequence.Count.ToString();
            info += " calculation record(s) will be deleted.";
            DialogResult res = MessageBox.Show(info, "FTReactorUnit", MessageBoxButtons.OKCancel);
            if (res == DialogResult.OK)
            {
                calcSequence.Clear();
            }
        }

        /// <summary>
        /// View the recycle calculation interim data directly.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments</param>
        private void buttonViewCalcSeq_Click(object sender, EventArgs e)
        {
            ViewCalcSequence();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Import the conversion coefficients from the outside source.
        /// </summary>
        /// <param name="filePath">The excel file path.</param>
        /// <param name="cellBeg">The excel cell string, such as "C2"</param>
        /// <param name="cellEnd">The excel cell string, such as "C46"</param>
        /// <returns>The coefficients list.</returns>
        private List<double> ImportDoubleArrayFromExcel(string filePath, string cellBeg, string cellEnd)
        {
            if (!File.Exists(filePath))
            {
                throw new InvalidOperationException("Invalid Excel file path");
            }

            List<double> ls = new List<double>();

            try
            {
                ApplicationClass app = new ApplicationClass();
                Workbook workBook = app.Workbooks.Open(filePath, 0, true, 5,
                    "", "", true, XlPlatform.xlWindows, "\t", false, false, 0,
                    true, true, XlCorruptLoad.xlNormalLoad);
                Worksheet workSheet = (Worksheet)workBook.ActiveSheet;

                // Excel.range is always a two-dimensional array
                Range range = workSheet.get_Range(cellBeg, cellEnd);
                System.Array values = (System.Array)range.Cells.Value2;
                for (int i = 0; i < values.Length; ++i)
                {
                    ls.Add(Double.Parse(values.GetValue(i + 1, 1).ToString()));
                }
                app.Workbooks.Close();
                app = null;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Import conefficients");

                // Roll back the result set.
                ls.Clear();     
            }
          
            return ls;
        }

        /// <summary>
        /// Import the double arrays from the outside Excel file.
        /// </summary>
        /// <param name="filePath">The Excel file path.</param>
        /// <param name="cells">The Excel cells in string list. The format is "cellBegin", "cellEnd",
        /// "cellBegin", "cellEnd"...</param>
        /// <returns>The double array list.</returns>
        private List<double[]> ImportDoubleArrayListFromExcel(string filePath, List<string> cells)
        {
            if (!File.Exists(filePath))
            {
                throw new InvalidOperationException("Invalid Excel file path");
            }
            if (cells == null || (cells.Count % 2 != 0))
            {
                throw new ArgumentException("The cells are not specified rightly.", "cells");
            }

            List<double[]> ls = new List<double[]>();
            if (cells.Count == 0)
            {
                return ls;
            }

            try
            {
                ApplicationClass app = new ApplicationClass();
                Workbook workBook = app.Workbooks.Open(filePath, 0, true, 5,
                    "", "", true, XlPlatform.xlWindows, "\t", false, false, 0,
                    true, true, XlCorruptLoad.xlNormalLoad);
                Worksheet workSheet = (Worksheet)workBook.ActiveSheet;

                List<double> tempList = new List<double>(128);
                for (int i = 0; i < cells.Count; i+=2)
                {
                    tempList.Clear();
                    // Excel.range is always a two-dimensional array
                    Range range = workSheet.get_Range(cells[i], cells[i + 1]);

                    if (range.Cells.Value2 is System.Array)
                    {
                        System.Array values = (System.Array)range.Cells.Value2;
                        for (int j = 0; j < values.Length; ++j)
                        {
                            tempList.Add(Double.Parse(values.GetValue(j + 1, 1).ToString()));
                        }
                        ls.Add(tempList.ToArray());
                    }
                    else if (range.Cells.Value2 is Double)
                    {
                        ls.Add(new double[] { (Double)range.Cells.Value2 });
                    }
                    else
                    {
                        throw new InvalidOperationException("Excel cells can not be converted other than doubel array or double.");
                    }
                }

                app.Workbooks.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Import Properties");

                // Roll back the result set.
                ls.Clear();
            }

            return ls;
        }

        /// <summary>
        /// Fill the conversion coefficients to the list view.
        /// </summary>
        /// <param name="coeff">the coefficients array.</param>
        private void FillCoeff(double[] coeff)
        {
            if (coeff.Length != listViewConvCoeffIn.Items.Count)
            {
                throw new InvalidOperationException("The coeff count is not match");
            }

            for (int i = 0; i < coeff.Length; ++i)
            {
                if (listViewConvCoeffIn.Items[i].SubItems.Count > 1)
                {
                    listViewConvCoeffIn.Items[i].SubItems.RemoveAt(1);
                }
                listViewConvCoeffIn.Items[i].SubItems.Add(coeff[i].ToString());
            }
        }

        /// <summary>
        /// Fill the RxnID to the list view.
        /// </summary>
        /// <param name="rxnID">the RxnID array.</param>
        private void FillRxnID(string[] rxnID)
        {
            listViewConvCoeffIn.Items.Clear();
            foreach (string id in rxnID)
            {
                listViewConvCoeffIn.Items.Add(id);
            }
        }

        /// <summary>
        /// Fill the STY(coupling with temperature) table.
        /// </summary>
        /// <param name="sty">The STY list.</param>
        private void FillSTYTable(List<KeyValuePair<double, double>> sty)
        {
            listViewSTY.Items.Clear();
            foreach (KeyValuePair<double, double> pair in sty)
            {
                ListViewItem item = listViewSTY.Items.Add(pair.Key.ToString());
                item.SubItems.Add(pair.Value.ToString());
                ListViewItem item1 = listViewSTY_II.Items.Add(pair.Key.ToString());
                item1.SubItems.Add(pair.Value.ToString());
            }
        }

        /// <summary>
        /// Validate the user input in the text box as a float vlaue.
        /// If the input is validate, it will be assign to the "userInput" parameter.
        /// </summary>
        /// <param name="box">The text box control.</param>
        /// <param name="?">The user input reference.</param>
        private void ValidateTextBoxInputAsFloat(System.Windows.Forms.TextBox box, ref double userInput)
        {
            double val = 0.0;
            if (Double.TryParse(box.Text, out val))
            {
                userInput = val;
                box.ForeColor = Color.Black;
            }
            else
            {
                box.ForeColor = Color.Red;
            }
        }

        /// <summary>
        /// Calculate the Xco coupling with k and display the result on UI.
        /// </summary>
        private void CalcXcoWithSTYAndDisplay()
        {
            double Xco = 0;
            try
            {
                double sty = FTPropPackage.GetSTYByTemperature(fixedTemperature, spaceTimeYields);
                Xco = FTPropPackage.CalcXcoUsingSTY(kCoeff, sty, reactorVol, inputTotalFlow,
                    fixedTemperature + 273.15, inputPressure * 100000);
            }
            catch (Exception)
            {
            }
            labelXco.Text = "Xco coupling with K: " + Xco.ToString();
        }

        /// <summary>
        /// Calculate the yield of CH4 with k1, STY and H2/CO ratio.
        /// </summary>
        private void CalcCH4YieldAndDisplay()
        {
            double yieldCH4 = 0;
            try
            {
                double sty = FTPropPackage.GetSTYByTemperature(fixedTemperature, spaceTimeYields);
                yieldCH4 = FTPropPackage.CalcYCH4UsingH2CORatio(k1Coeff, sty, reactorVol, inputTotalFlow,
                    fixedTemperature + 273.15, inputPressure * 100000, ratioH2CO);
            }
            catch (Exception)
            {

            }
            labelYieldCH4.Text = "YCH4 coupling with k1: " + yieldCH4.ToString();     
        }

        /// <summary>
        /// Calculate the yield of CH4 with k1, STY and H2/CO ratio.
        /// </summary>
        private void CalcC2PlusYieldAndDisplay()
        {
            double yieldC2Plus = 0;
            try
            {
                double sty = FTPropPackage.GetSTYByTemperature(fixedTemperature, spaceTimeYields);
                yieldC2Plus = FTPropPackage.CalcYC2PlusUsingH2CORatio(k2Coeff, sty, reactorVol, inputTotalFlow,
                    fixedTemperature + 273.15, inputPressure * 100000, ratioH2CO);
            }
            catch (Exception)
            {

            }
            labelYieldC2Plus.Text = "YC2+ coupling with k2: " + yieldC2Plus.ToString();
        }

        /// <summary>
        /// Export the calulation sequence to the file.
        /// </summary>
        private void ExportCalcSequence()
        {
            DialogResult result = saveCalcSeqDialog.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                using (TextWriter tw = new StreamWriter(saveCalcSeqDialog.FileName))
                {
                    foreach (IntermCalcData data in calcSequence)
                    {
                        tw.WriteLine(data.BuildString());      
                    }
                }
            }
        }

        /// <summary>
        /// View the recycle calulation sequence in notepad.exe.
        /// </summary>
        private void ViewCalcSequence()
        {
            string tempFile = Path.GetTempFileName();
            using (TextWriter tw = new StreamWriter(tempFile))
            {
                foreach (IntermCalcData data in calcSequence)
                {
                    tw.WriteLine(data.BuildString());
                }
            }
            System.Diagnostics.Process.Start("notepad.exe", tempFile);
        }

        #endregion

        #region UI Control Event Hanlers - Mode I

        /// <summary>
        /// Validate the k coefficient value.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void textBoxKCoeff_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxKCoeff, ref kCoeff);
            CalcXcoWithSTYAndDisplay();
        }

        /// <summary>
        /// Validate the reactor volume value.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void textBoxReactorVol_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxReactorVol, ref reactorVol);
        }

        /// <summary>
        /// Set the selectivity calulation alpha value.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event argument.</param>
        private void textBoxSelAlpha_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxSelAlpha, ref selAlpha);
        }

        #endregion

        #region UI Control Event Hanlers - Mode II

        /// <summary>
        /// Validate the k1 coeffecient input.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void textBoxK1_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxK1, ref k1Coeff);
            CalcCH4YieldAndDisplay();
        }

        /// <summary>
        /// Validate the k2 coeffecient input.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void textBoxK2_TextChanged(object sender, EventArgs e)
        {
            ValidateTextBoxInputAsFloat(textBoxK2, ref k2Coeff);
            CalcC2PlusYieldAndDisplay();
        }

        #endregion
    }
}
